home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / compstol / cmpsttl1.lha / CompositeTool / v1.1.dist / HDF / dfr8.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-08  |  29.6 KB  |  850 lines

  1. /*****************************************************************************
  2. *              NCSA HDF version 3.00
  3. *                December, 1989
  4. *
  5. * NCSA HDF Version 3.00 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************/
  16.  
  17. /*-----------------------------------------------------------------------------
  18.  * File:    dfr8.c
  19.  * Purpose: read and write 8-bit Raster Image Groups
  20.  * Invokes: df.c, dfcomp.c, dfgroup.c, dfrig.h
  21.  * Contents: 
  22.  *  DFR8getdims: retrieve information about 8-bit image dimensions
  23.  *  DFR8getimage: retrieve 8-bit image and associated palette
  24.  *  DFR8setpalette: specify palette to be used with subsequent 8-bit images
  25.  *  DFR8Iputimage: internal routine that write 8-bit images to files
  26.  *  DFR8putimage: write 8-bit image into an HDF file
  27.  *  DFR8addimage: append another 8-bit image to an HDF file
  28.  *  DFR8getrig: read in a raster image group for 8-bit images
  29.  *  DFR8putrig: write out a raster image group for 8-bit images
  30.  *  DFR8nimages: number of images in HDF file
  31.  *  DFR8readref: get image with this reference number next
  32.  *  DFR8writeref: put image with this reference number next
  33.  *  DFR8restart: forget info about last file accessed - restart from beginning
  34.  *  DFR8lastref: return reference number of last element read or written
  35.  *  DFR8Iopen: open/reopen file
  36.  *  DFR8Iriginfo: obtain info about next RIG/RI8 to get
  37.  * Remarks: A RIG specifies attributes associated with an image - palette, 
  38.  *          dimension, compression, color compensation etc.
  39.  *          The palette for an 8-bit image is assumed to always be 768 bytes
  40.  *          The palette is arranged as RGBRGB...
  41.  *---------------------------------------------------------------------------*/
  42.  
  43.  
  44. #include "dfrig.h"
  45.  
  46. static int foundRig = -1;    /* -1: don't know if HDF file has RIGs */
  47.                 /* 0: No RIGs, try for RI8s etc. */
  48.                 /* 1: RIGs used, ignore RI8s etc. */
  49. static DFRrig Readrig;        /* information about RIG being read */
  50. static DFRrig Writerig;        /* information about RIG being written */
  51. static int Newdata = 0;        /* does Readrig contain fresh data? */
  52. static uint16 Writeref=0;    /* ref of next image to put in this file */
  53. static int Newpalette=(-1);    /* -1 = no palette is associated */
  54.                 /* 0 = palette already written out */
  55.                 /* 1 = new palette, not yet written out */
  56. static char Palette[768];    /* to store palette for 8-bit images */
  57. static uint16 Refset=0;        /* Ref of image to get next */
  58. static uint16 Lastref = 0;    /* Last ref read/written */
  59. static DFRrig Zrig = {        /* empty RIG for initialization */
  60.     {0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
  61.     {0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
  62.     {0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
  63.     0, 0, 0.0, 0.0, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0},
  64.     {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, NULL
  65. };
  66.  
  67. #ifndef VMS
  68. DF *DFR8Iopen();
  69. #else /*VMS*/
  70. DF *_DFR8Iopen();
  71. #endif
  72.  
  73. typedef struct R8dim {
  74.     uint16 xd;
  75.     uint16 yd;
  76. } R8dim;            /* dimensions of raster-8 image */
  77.  
  78.  
  79. /*-----------------------------------------------------------------------------
  80.  * Name:    DFR8getdims
  81.  * Purpose: get dimensions of next image from RIG, also if there is a palette
  82.  * Inputs:  filename: name of HDF file
  83.  *          pxdim, pxdim, pointer to locations for returning x,y dimensions
  84.  *          pispal: pointer to location for rtning whether there is a palette
  85.  * Returns: 0 on success, -1 on failure with DFerror set
  86.  *          *pxdim, *pydim are set to dimensions of the next image
  87.  *          *pispal is set to 1 if a palette is associated with it, else 0
  88.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  89.  * Invokes: DFR8Iopen, DFclose, DFR8Iriginfo, DFIerr
  90.  * Remarks: will also handle file with just raster-8 tags: RI8, CI8, ID8, IP8
  91.  *---------------------------------------------------------------------------*/
  92.  
  93. int DFR8getdims(filename, pxdim, pydim, pispal)
  94. char *filename;
  95. int32 *pxdim, *pydim;
  96. int *pispal;
  97. {
  98.     DF *dfile;
  99.  
  100.     DFerror = DFE_NOERROR;
  101.  
  102.     if (!pxdim || !pydim) {    /* check for zero dimensions */
  103.         DFerror = DFE_BADPTR;
  104.         return(-1);
  105.     }
  106.  
  107.     dfile = DFR8Iopen(filename, DFACC_READ);
  108.     if (dfile == NULL) return(-1);
  109.  
  110.     if (DFR8Iriginfo(dfile)<0)    /* reads next RIG or RI8 from file */
  111.         return(DFIerr(dfile));    /* on error, close file and return -1 */
  112.  
  113.     Newdata = 1;
  114.     *pxdim = Readrig.descimage.xdim;
  115.     *pydim = Readrig.descimage.ydim;
  116.     if (pispal) *pispal = Readrig.lut.tag ? 1 : 0; /* is there a palette */
  117.  
  118.     return(DFclose(dfile));
  119. }
  120.  
  121. /*-----------------------------------------------------------------------------
  122.  * Name:    DFR8getimage
  123.  * Purpose: get next image from a RIG, get palette also if desired
  124.  * Inputs:  filename: name of HDF file
  125.  *          image: space to read image into
  126.  *          xdim, ydim: dimensions of space allocated by user for image
  127.  *          pal: 768-byte space for palette, null if palette not wanted
  128.  * Returns: 0 on success, -1 on failure with DFerror set
  129.  *          image in image, palette in pal
  130.  * Users:   HDF HLL users, utilities, other routines
  131.  * Invokes: DFR8Iopen, DFR8Iriginfo, DFIerr, DFclose, DFgetelement, DFgetcomp
  132.  * Remarks: Will also get RI8s and CI8s if no RIGs in file
  133.  *          Normally,DFR8getdims is called first and it finds next image to get
  134.  *          But if that is not called, DFR8getimage will itself find next image
  135.  *          Automatically decompresses images
  136.  *---------------------------------------------------------------------------*/
  137.  
  138. int DFR8getimage(filename, image, xdim, ydim, pal)
  139. char *filename;
  140. int32 xdim, ydim;
  141. char *image;
  142. char *pal;
  143. {
  144.     DF *dfile;
  145.  
  146.     DFerror = DFE_NOERROR;
  147.  
  148.     if ((xdim<=0) || (ydim<=0)) {
  149.         DFerror = DFE_BADDIM;
  150.         return(-1);
  151.     }
  152.  
  153.     dfile = DFR8Iopen(filename, DFACC_READ);
  154.     if (dfile == NULL) return(-1);
  155.  
  156.     if (!Newdata) {        /* if Readrig not fresh */
  157.         if (DFR8Iriginfo(dfile)<0) /* reads next RIG or RI8 from file */
  158.             return(DFIerr(dfile)); /* on error, close file and return -1 */
  159.     }
  160.     Newdata = 0;        /* read new RIG next time */
  161.  
  162.     if ((Readrig.descimage.xdim > xdim) || (Readrig.descimage.ydim > ydim)) {
  163.         DFerror = DFE_NOTENOUGH; /* not enough space */
  164.         return(DFIerr(dfile));
  165.     }
  166.  
  167.     /* read image */
  168.     if (Readrig.descimage.compr.tag) { /* compressed image */
  169.         if (DFgetcomp(dfile, Readrig.image.tag, Readrig.image.ref, image,
  170.               Readrig.descimage.xdim, Readrig.descimage.ydim,
  171.               Readrig.descimage.compr.tag)<0)
  172.             return(DFIerr(dfile));
  173.     } else {            /* non-compressed raster image */
  174.         if (DFgetelement(dfile, Readrig.image.tag, Readrig.image.ref, image)<0)
  175.             return(DFIerr(dfile));
  176.     }
  177.  
  178.     if (pal && Readrig.lut.tag) { /* read palette */
  179.         if (DFgetelement(dfile, Readrig.lut.tag, Readrig.lut.ref, pal)<0)
  180.             return(DFIerr(dfile));
  181.     }
  182.     return(DFclose(dfile));
  183. }
  184.  
  185. /*-----------------------------------------------------------------------------
  186.  * Name:    DFR8setpalette
  187.  * Purpose: set palette for subsequent images
  188.  * Inputs:  pal: palette to set
  189.  * Returns: 0 on success, -1 on failure with DFerror set
  190.  * Users:   HDF users, utilities, other routines
  191.  * Invokes: none
  192.  * Remarks: if pal is NULL, no palette is associated with subsequent images
  193.  *---------------------------------------------------------------------------*/
  194.  
  195. int DFR8setpalette(pal)
  196. char *pal;
  197. {
  198.     int i;
  199.  
  200.     DFerror = DFE_NOERROR;
  201.  
  202.     if (!pal) {
  203.         Newpalette = -1;    /* no palette */
  204.         Writerig.lut.tag = 0;
  205.         Writerig.lut.ref = 0;   /* forget tag/ref of previous palette */
  206.         Writerig.desclut.xdim = 0;
  207.         Writerig.desclut.ncomponents = 0;
  208.     } else {            /* store palette */
  209.         for (i=0; i<768; i++)
  210.             Palette[i] = pal[i];
  211.         Newpalette = 1;
  212.     }
  213.     return(0);
  214. }
  215.  
  216. /*-----------------------------------------------------------------------------
  217.  * Name:    DFR8Iputimage
  218.  * Purpose: Internal routine to write RIG to file
  219.  * Inputs:  filename: name of HDF file
  220.  *          image: image to be written to file
  221.  *          xdim, ydim: dimensions of image
  222.  *          compress: compression scheme to be used on image, 0 if none
  223.  *                    possible values are DFTAG_RLE and DFTAG_IMC
  224.  *          op: 0 will overwrite existing file, 1 will append image to file
  225.  * Returns: 0 on success, -1 on failure with DFerror set
  226.  * Users:   HDF systems programmers, DFR8putimage, DFR8addimage
  227.  * Invokes: DFR8Iopen, DFclose, DFputelement, DFdup, DFR8putrig, DFputcomp,
  228.  *          DFIerr
  229.  * Remarks: Palette will be associated with image is isPalette is 1
  230.  *          Palette will be written to file if not written before (Palref=0)
  231.  *          Creates both RIG and RI8/CI8 tags, to accomodate older programs
  232.  *---------------------------------------------------------------------------*/
  233.  
  234. int DFR8Iputimage(filename, image, xdim, ydim, compress, op)
  235. char *filename;
  236. int32 xdim, ydim;
  237. char *image;
  238. int compress;               /* compression scheme */
  239. int op;                     /* 0 is a put, 1 is a putnext */
  240. {
  241.     int access;             /* create if op 0, write if op 1 */
  242.     DF *dfile;
  243.     uint16 r8tag;           /* RIG and raster tags of image being written */
  244.     char *pal;     /* pointer to palette to be written */
  245.     char newpal[768];  /* Imcomp creates new palette to be associated*/
  246.     int wdim;               /* have dimensions already been written out? */
  247.  
  248.     DFerror = DFE_NOERROR;
  249.  
  250.     if ((xdim<=0) || (ydim<=0)) {
  251.         DFerror = DFE_BADDIM;
  252.         return(-1);
  253.     }
  254.     if (!image) {
  255.         DFerror = DFE_BADPTR;
  256.         return(-1);
  257.     }
  258.     pal = (Newpalette>=0) ? Palette : NULL;
  259.     access = op ? DFACC_WRITE : DFACC_CREATE;
  260.  
  261.     dfile = DFR8Iopen(filename, access);
  262.     if (dfile==NULL) return(-1);
  263.  
  264.     if (!Writeref) Writeref = DFnewref(dfile);
  265.     if (!Writeref) return(-1);
  266.  
  267.     /* write out image */
  268.     if (compress) {
  269.         if (DFputcomp(dfile, DFTAG_CI, Writeref, image, xdim, ydim,
  270.               pal, newpal, compress)<0)
  271.             return(DFIerr(dfile));
  272.         Writerig.image.tag = DFTAG_CI;
  273.         if (compress==DFTAG_IMC) {
  274.             pal = newpal;    /* Imcomp creates new pal */
  275.             Newpalette = 1;    /* write out palette */
  276.         }
  277.     } else {            /* image need not be compressed */
  278.         if (DFputelement(dfile, DFTAG_RI, Writeref, image, xdim*ydim)<0)
  279.             return(DFIerr(dfile));
  280.         Writerig.image.tag = DFTAG_RI;
  281.     }
  282.     Writerig.image.ref = Writeref;
  283.     Writerig.descimage.ncomponents = 1;
  284.     Writerig.aspectratio = 1.0;
  285.  
  286.     /* Write out Raster-8 tags for those who want it */
  287.     r8tag = compress ?
  288.     ((compress==DFTAG_RLE) ? DFTAG_CI8 : DFTAG_II8) : DFTAG_RI8;
  289.     if (DFdup(dfile, r8tag, Writeref, Writerig.image.tag, Writeref)<0)
  290.         return(DFIerr(dfile));
  291.  
  292.     /* Write out palette */
  293.     if (pal) {            /* if there is a palette */
  294.         if (Newpalette==1) {    /* write palette */
  295.             if (DFputelement(dfile, DFTAG_LUT, Writeref, pal, (int32) 768)<0)
  296.                 return(DFIerr(dfile));
  297.             Writerig.lut.tag = DFTAG_LUT;
  298.             Writerig.lut.ref = Writeref;
  299.             Writerig.desclut.xdim = 768;
  300.             Writerig.desclut.ncomponents = 1;
  301.         }
  302.         if (compress!=DFTAG_IMC) Newpalette = 0;
  303.     /* if IMCOMP, original palette not written out */
  304.  
  305.     /* put in Raster-8 stuff also, for those who want it */
  306.         if (DFdup(dfile, DFTAG_IP8, Writeref, Writerig.lut.tag,
  307.           Writerig.lut.ref)<0)
  308.             return(DFIerr(dfile));
  309.     }
  310.  
  311.     /* Write out RIG */
  312.     if ((Writerig.descimage.xdim==xdim) && (Writerig.descimage.ydim==ydim) &&
  313.     (Writerig.descimage.compr.tag==compress))
  314.         wdim = 0;
  315.     else {
  316.         wdim = 1;
  317.         Writerig.descimage.xdim = xdim;
  318.         Writerig.descimage.ydim = ydim;
  319.         Writerig.descimage.compr.tag = compress;
  320.     }
  321.     if (DFR8putrig(dfile, Writeref, &Writerig, wdim)<0) /* writes ID, NT */
  322.         return(DFIerr(dfile));
  323.  
  324.     Lastref = Writeref;        /* remember ref written */
  325.  
  326.     Writeref = 0;               /* don't know ref to write next */
  327.  
  328.     return(DFclose(dfile));
  329. }
  330.  
  331. /*-----------------------------------------------------------------------------
  332.  * Name:    DFR8putimage
  333.  * Purpose: Write RIG to HDF file
  334.  * Inputs:  filename: name of HDF file
  335.  *          image: image to be written to file
  336.  *          xdim, ydim: dimensions of image
  337.  *          compress: compression scheme to be used on image, 0 if none
  338.  * Returns: 0 on success, -1 on failure with DFerror set
  339.  * Users:   HDF HLL users, utilities, other routines
  340.  * Invokes: DFR8Iputimage
  341.  * Remarks: overwrites existing HDF file
  342.  *---------------------------------------------------------------------------*/
  343.  
  344. int DFR8putimage(filename, image, xdim, ydim, compress)
  345. char *filename;
  346. int32 xdim, ydim;
  347. char *image;
  348. int compress;
  349. {
  350.     return(DFR8Iputimage(filename, image, xdim, ydim, compress, 0));
  351. }
  352.  
  353.  
  354. /*-----------------------------------------------------------------------------
  355.  * Name:    DFR8addimage
  356.  * Purpose: Append RIG to HDF file
  357.  * Inputs:  filename: name of HDF file
  358.  *          image: image to be written to file
  359.  *          xdim, ydim: dimensions of image
  360.  *          compress: compression scheme to be used on image, 0 if none
  361.  * Returns: 0 on success, -1 on failure with DFerror set
  362.  * Users:   HDF HLL users, utilities, other routines
  363.  * Invokes: DFR8Iputimage
  364.  * Remarks: inserts image into existing file, will create file if necessary
  365.  *---------------------------------------------------------------------------*/
  366.  
  367. int DFR8addimage(filename, image, xdim, ydim, compress)
  368. char *filename;
  369. int32 xdim, ydim;
  370. char *image;
  371. int compress;
  372. {
  373.     return(DFR8Iputimage(filename, image, xdim, ydim, compress, 1));
  374. }
  375.  
  376.  
  377. /*****************************************************************************/
  378. /* This is the next lower layer - procedures to get and put a RIG. */
  379. /* These are specific to 8-bit
  380. /*****************************************************************************/
  381.  
  382. /*-----------------------------------------------------------------------------
  383.  * Name:    DFR8getrig
  384.  * Purpose: Read a RIG into memory
  385.  * Inputs:  dfile: pointer to HDF file containing RIG
  386.  *          ref: reference number of RIG to get
  387.  *          rig: struct in which to place info obtained
  388.  * Returns: 0 on success, -1 on failure with DFerror set
  389.  *          contents of RIG in the struct rig
  390.  * Users:   HDF programmers, utilities, DFR8getdims,DFR8getimage
  391.  * Invokes: DFdiget, DFdinext, DFIcheck, DFgetelement
  392.  * Remarks: assumes 8-bit
  393.  *---------------------------------------------------------------------------*/
  394.  
  395. int DFR8getrig(dfile, ref, rig)
  396. DF *dfile;
  397. uint16 ref;
  398. DFRrig *rig;
  399. {
  400.     DFdi elmt;
  401.     char ntstring[4];
  402.  
  403.     DFerror = DFE_NOERROR;
  404.  
  405.     if (DFIcheck(dfile))
  406.         return( -1);
  407.     if (!ref) {
  408.         DFerror = DFE_BADREF;
  409.         return(-1);
  410.     }
  411.  
  412.     if (DFdiread(dfile, DFTAG_RIG, ref)<0) /* read RIG into memory */
  413.         return(-1);
  414.  
  415.     *rig = Zrig;        /* fill rig with zeroes */
  416.     while (!DFdiget(&elmt)) {    /* get next tag/ref from RIG */
  417.         switch (elmt.tag) {    /* process tag/ref */
  418.             case DFTAG_CI:
  419.             case DFTAG_RI:
  420.                 rig->image.tag = elmt.tag; /* put tag/ref in struct */
  421.                 rig->image.ref = elmt.ref;
  422.                 break;
  423.             case DFTAG_LUT:
  424.                 rig->lut.tag = elmt.tag;
  425.                 rig->lut.ref = elmt.ref;
  426.                 break;
  427.             case DFTAG_ID:    /* read description info */
  428. #ifdef DF_STRUCTOK
  429.                 if (DFgetelement(dfile, elmt.tag, elmt.ref, &rig->descimage)<0)
  430.                     return(-1);
  431. #else /*DF_STRUCTOK*/
  432.                 if (DFgetelement(dfile, elmt.tag, elmt.ref, DFtbuf)>0) {
  433.                     register char *p;
  434.                     p = DFtbuf;
  435.                     INT32READ(p, rig->descimage.xdim);
  436.                     INT32READ(p, rig->descimage.ydim);
  437.                     UINT16READ(p, rig->descimage.nt.tag);
  438.                     UINT16READ(p, rig->descimage.nt.ref);
  439.                     INT16READ(p, rig->descimage.ncomponents);
  440.                     INT16READ(p, rig->descimage.interlace);
  441.                     UINT16READ(p, rig->descimage.compr.tag);
  442.                     UINT16READ(p, rig->descimage.compr.ref);
  443.                 } else
  444.                     return(-1);
  445. #endif /*DF_STRUCTOK*/
  446.                 if (rig->descimage.ncomponents!=1) {
  447.                     DFerror = DFE_BADCALL;
  448.                     return(-1);
  449.                 }
  450.                 if (rig->descimage.nt.tag==0) break; /* old RIGs */
  451.  
  452.         /* read NT */
  453.                 if (DFgetelement(dfile, rig->descimage.nt.tag,
  454.                  rig->descimage.nt.ref, ntstring)<0)
  455.                     return(-1);
  456.                 if ((ntstring[2]!=8) || (ntstring[1]!=DFNT_UCHAR)) {
  457.                     DFerror = DFE_BADCALL;
  458.                     return(-1);
  459.                 }
  460.                 break;
  461.             default:        /* ignore unknown tags */
  462.                 break;
  463.         }
  464.     }
  465.     return(0);
  466. }
  467.  
  468. /*-----------------------------------------------------------------------------
  469.  * Name:    DFR8putrig
  470.  * Purpose: Write RIG struct out to HDF file
  471.  * Inputs:  dfile: HDF file pointer
  472.  *          ref: ref to put RIG with
  473.  *          rig: struct containing RIG info to put
  474.  *          wdim: if 1, write out new description records. if 0 already written
  475.  * Returns: 0 on success, -1 on failure with DFerror set
  476.  * Users:   HDF programmers, utilities, DFR8Iputimage, other routines
  477.  * Invokes: DFIcheck, DFdistart, DFdiadd, DFdiend, DFputelement
  478.  * Remarks: assumes 8-bit.  Writes out NT if necessary, ID, ID8 if told to
  479.  *---------------------------------------------------------------------------*/
  480.  
  481. int DFR8putrig(dfile, ref, rig, wdim)
  482. DF *dfile;
  483. uint16 ref;
  484. DFRrig *rig;
  485. int wdim;
  486. {
  487.     static uint16 prevdimref=0; /*ref of previous dimension record, to reuse */
  488.     R8dim im8dim;
  489.     char ntstring[4];
  490.  
  491.     DFerror = DFE_NOERROR;
  492.  
  493.     if (DFIcheck(dfile))
  494.         return( -1);
  495.     if (!ref) {
  496.         DFerror = DFE_BADREF;
  497.         return(-1);
  498.     }
  499.  
  500.     if (!rig->descimage.nt.tag) {
  501.     /* construct and write out NT */
  502.         ntstring[0] = DFNT_VERSION; /* version */
  503.         ntstring[1] = DFNT_UCHAR; /* type */
  504.         ntstring[2] = 8;    /* width: RIG data is 8-bit chars */
  505.         ntstring[3] = DFNTC_BYTE; /* class: data are numeric values */
  506.         if (DFputelement(dfile, DFTAG_NT, ref, ntstring, (int32) 4) <0)
  507.             return(-1);
  508.         rig->descimage.nt.tag = DFTAG_NT;
  509.         rig->descimage.nt.ref = ref;
  510.     }
  511.         
  512.     im8dim.xd = rig->descimage.xdim;
  513.     im8dim.yd = rig->descimage.ydim;
  514.     if (wdim) {
  515. #ifdef DF_STRUCTOK        /* write out description record */
  516.         if (DFputelement(dfile, DFTAG_ID8, ref, &im8dim, (int32) 4)<0) /*ID8 */
  517.             return(-1);
  518.         if (DFputelement(dfile, DFTAG_ID, ref, &rig->descimage,    /* ID */
  519.              sizeof(rig->descimage))<0)
  520.             return(-1);
  521. #else /*DF_STRUCTOK*/
  522.         register char *p;
  523.         p = DFtbuf;
  524.         INT32WRITE(p, rig->descimage.xdim);
  525.         INT32WRITE(p, rig->descimage.ydim);
  526.         UINT16WRITE(p, rig->descimage.nt.tag);
  527.         UINT16WRITE(p, rig->descimage.nt.ref);
  528.         INT16WRITE(p, rig->descimage.ncomponents);
  529.         INT16WRITE(p, rig->descimage.interlace);
  530.         UINT16WRITE(p, rig->descimage.compr.tag);
  531.         UINT16WRITE(p, rig->descimage.compr.ref);
  532.         if (DFputelement(dfile, DFTAG_ID, ref, DFtbuf,(int32)(p-DFtbuf))<0)
  533.             return(-1);
  534.     /* write out ID8 */
  535.         p = DFtbuf;
  536.         UINT16WRITE(p, im8dim.xd);
  537.         UINT16WRITE(p, im8dim.yd);
  538.         if (DFputelement(dfile, DFTAG_ID8, ref, DFtbuf, (int32) 4)<0)
  539.             return(-1);
  540. #endif /*DF_STRUCTOK*/
  541.         prevdimref = ref;
  542.     }
  543.     if (!prevdimref) {
  544.         DFerror = DFE_BADDIM;
  545.         return(-1);
  546.     }
  547.  
  548.     /* prepare to start writing rig */
  549.     /* ### NOTE: the second parameter to this call may go away */
  550.     if (DFdisetup(10)<0) return(-1); /* max 10 tag/refs in set */
  551.  
  552.     /* add tag/ref to RIG - image description, image and palette */
  553.     if (DFdiput(DFTAG_ID, prevdimref) < 0) return(-1);
  554.  
  555.     if (DFdiput(rig->image.tag, rig->image.ref) < 0) return(-1);
  556.  
  557.     if (rig->lut.ref)
  558.         if (DFdiput(rig->lut.tag, rig->lut.ref) < 0) return(-1);
  559.  
  560.         /* write out RIG */
  561.     return(DFdiwrite(dfile, DFTAG_RIG, ref));
  562. }
  563.  
  564.  
  565. /*-----------------------------------------------------------------------------
  566.  * Name:    DFR8nimages
  567.  * Purpose: How many images are present in this file?
  568.  * Inputs:  filename: name of HDF file
  569.  * Returns: number of images  on success, -1 on failure with DFerror set
  570.  * Users:   HDF programmers, other routines and utilities
  571.  * Invokes: DFR8Iopen, DFclose, DFnumber
  572.  * Remarks: the number is the number of RIGs if RIGs are present
  573.  *          If not, it is the number of RI8s + number of CI8s
  574.  *---------------------------------------------------------------------------*/
  575.  
  576. int DFR8nimages(filename)
  577. char *filename;
  578. {
  579.     DF *dfile;
  580.     int nimages=0;
  581.  
  582.     DFerror = DFE_NOERROR;
  583.  
  584.     /* should use reopen if same file as last time - more efficient */
  585.     dfile = DFR8Iopen(filename, DFACC_READ);
  586.     if (dfile==NULL) return(-1);
  587.  
  588.     /* find next rig */
  589.     if (foundRig) {        /* either RIGs present or don't know */
  590.         nimages = DFnumber(dfile, DFTAG_RIG); /* count number of RIGs */
  591.         if (nimages>=0) {
  592.             foundRig = 1;
  593.             if (DFclose(dfile)<0) return(-1);
  594.             return(nimages);
  595.         }
  596.         foundRig = 0;
  597.     }
  598.     nimages = DFnumber(dfile, DFTAG_RI8);
  599.     nimages += DFnumber(dfile, DFTAG_CI8);
  600.     if (DFclose(dfile)<0) return(-1);
  601.     return(nimages);
  602. }
  603.  
  604. /*-----------------------------------------------------------------------------
  605.  * Name:    DFR8readref
  606.  * Purpose: Set ref of image to get next
  607.  * Inputs:  filename: file to which this applies
  608.  *          ref: reference number of next get
  609.  * Returns: 0 on success, -1 on failure
  610.  * Users:   HDF programmers, other routines and utilities
  611.  * Invokes: DFR8Iopen, DFIfind
  612.  * Remarks: checks if image with this ref exists
  613.  *---------------------------------------------------------------------------*/
  614.  
  615. int DFR8readref(filename, ref)
  616. char *filename;
  617. uint16 ref;
  618. {
  619.     DF *dfile;
  620.     int cdd;
  621.     DFdle *dlep;
  622.  
  623.     DFerror = DFE_NOERROR;
  624.  
  625.     dfile = DFR8Iopen(filename, DFACC_READ);
  626.     if (dfile==NULL) return(-1);
  627.     if (DFIfind(dfile, DFTAG_RIG, ref, 1, 0, 0, &dlep, &cdd)<0)
  628.         if (DFIfind(dfile, DFTAG_RI8, ref, 1, 0, 0, &dlep, &cdd)<0)
  629.             if (DFIfind(dfile, DFTAG_CI8, ref, 1, 0, 0, &dlep, &cdd)<0)
  630.                 return(DFIerr(dfile));
  631.     Refset = ref;
  632.     return(DFclose(dfile));
  633. }
  634.  
  635. /*-----------------------------------------------------------------------------
  636.  * Name:    DFR8writeref
  637.  * Purpose: Set ref of image to put next
  638.  * Inputs:  filename: file to which this applies
  639.  *          ref: reference number of next put
  640.  * Returns: 0 on success, -1 on failure
  641.  * Users:   HDF programmers, other routines and utilities
  642.  * Invokes: DFR8Iopen, DFIfind
  643.  * Remarks: none
  644.  *---------------------------------------------------------------------------*/
  645.  
  646. /* shut lint up */
  647. /* ARGSUSED */
  648. int DFR8writeref(filename, ref)
  649. char *filename;
  650. uint16 ref;
  651. {
  652.     DFerror = DFE_NOERROR;
  653.  
  654.     Writeref = ref;
  655.     return(0);
  656. }
  657.  
  658. static char Lastfile[DF_MAXFNLEN];          /* last file opened */
  659.  
  660. /*-----------------------------------------------------------------------------
  661.  * Name:    DFR8restart
  662.  * Purpose: Do not remember info about file - get again from first image
  663.  * Inputs:  none
  664.  * Returns: 0 on success
  665.  * Users:   HDF programmers
  666.  * Remarks: Just reset Lastfile to NULL
  667.  *---------------------------------------------------------------------------*/
  668.  
  669. int DFR8restart()
  670. {
  671.     Lastfile[0] = '\0';
  672.     return(0);
  673. }
  674.  
  675.  
  676. /*-----------------------------------------------------------------------------
  677.  * Name:    DFR8lastref
  678.  * Purpose: Return last ref written or read
  679.  * Inputs:  none
  680.  * Globals: Lastref
  681.  * Returns: ref on success, -1 on error with DFerror set
  682.  * Users:   HDF users, utilities, other routines
  683.  * Invokes: none
  684.  * Method:  return Lastref
  685.  * Remarks: none
  686.  *---------------------------------------------------------------------------*/
  687.  
  688. int DFR8lastref()
  689. {
  690.     return((int) Lastref);
  691. }
  692.  
  693.  
  694.  
  695. /******************************************************************************/
  696. /*----------------------- Internal routines ---------------------------------*/
  697. /******************************************************************************/
  698.  
  699.  
  700. /*-----------------------------------------------------------------------------
  701.  * Name:    DFR8Iopen
  702.  * Purpose: open or reopen a file
  703.  * Inputs:  filename: name of file to open
  704.  *          access : access mode
  705.  * Returns: file pointer on success, NULL on failure with DFerror set
  706.  * Users:   HDF systems programmers, all the RIG routines 
  707.  * Invokes: DFopen
  708.  * Remarks: This is a hook for someday providing more efficient ways to
  709.  *          reopen a file, to avoid re-reading all the headers
  710.  *---------------------------------------------------------------------------*/
  711.  
  712. DF *DFR8Iopen(filename, access)
  713. char *filename;
  714. int access;
  715. {
  716.  
  717.     DF *dfile;
  718.  
  719.     /* use reopen if same file as last time - more efficient */
  720.     if (strncmp(Lastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) {
  721.                 /* treat create as different file */
  722.         if (!(dfile = DFopen(filename, access, -1))) return(NULL);
  723.         foundRig = -1;        /* don't know if any RIGs in file */
  724.         Refset = 0;        /* no ref to get set for this file */
  725.         Newdata = 0;
  726.         Readrig = Zrig;        /* blank out read/write RIGs */
  727.         Writerig = Zrig;
  728.         if (Newpalette!=(-1)) Newpalette = 1; /* need to write out palette */
  729.     } else
  730.         if (!(dfile = DFopen(filename, access, -1))) return(NULL);
  731.  
  732.     strncpy(Lastfile, filename, DF_MAXFNLEN);
  733.     /* remember filename, so reopen may be used next time if same file */
  734.     return(dfile);
  735. }
  736.  
  737. /*-----------------------------------------------------------------------------
  738.  * Name:    DFR8Iriginfo
  739.  * Purpose: Getinformation about next RIG or Raster-8 in file
  740.  * Inputs:  dfile: pointer to DF file
  741.  * Returns: 0 on success, -1 on failure with DFerror set
  742.  * Users:   HDF systems programmers
  743.  * Invokes: DFIfind, DFgetelement
  744.  * Remarks: checks for RIGs first, then RI8s
  745.  *          if Refset set, gets image with that ref, if any
  746.  *---------------------------------------------------------------------------*/
  747.  
  748. int DFR8Iriginfo(dfile)
  749. DF *dfile;
  750. {
  751.     DFdle *dlep;
  752.     int cdd;
  753.     uint16 riref=0, ciref=0;
  754.  
  755. #ifdef DF_STRUCTOK
  756.     R8dim im8dim;
  757. #endif /*DF_STRUCTOK*/
  758.  
  759.     /* find next rig */
  760.     if (foundRig) {        /* either RIGs present or don't know */
  761.     do {
  762.         DFerror = DFE_NOERROR;
  763.         if (Refset &&
  764.         DFIfind(dfile, DFTAG_RIG, Refset, 1,0,0, &dlep, &cdd)<0) {
  765.         /* try for RI8 and CI8s */
  766.         }
  767.             /* in next line, !ref is passed for isfirst.  If we have found
  768.            a ref before, ref is non-zero, hence isfirst is 0.  If
  769.            we have not found anything yet, ref is 0 and isfirst is 1 */
  770.         else if (!Refset && DFIfind(dfile, DFTAG_RIG, DFREF_WILDCARD,
  771.                     !Readrig.image.ref, Readrig.image.tag,
  772.                                         Readrig.image.ref, &dlep, &cdd) <0) {
  773.         if (foundRig==1) { /* RIGs present, but no more to return */
  774.             DFerror = DFE_NOMATCH;
  775.             return(-1);
  776.         }
  777.         foundRig = 0;    /* No RIGs present in file */
  778.         }
  779.         else {        /* RIG found */
  780.         if (DFR8getrig(dfile, dlep->dd[cdd].ref, &Readrig)<0) {
  781.             if (Refset || (DFerror != DFE_BADCALL)) {
  782.             Refset = 0;
  783.             return(-1);
  784.             }
  785.             Readrig.image.ref = dlep->dd[cdd].ref; /*to get next one */
  786.         } else { foundRig = 1; Refset = 0; }
  787.         }
  788.     } while (DFerror==DFE_BADCALL);
  789.     }
  790.     if (Refset || !foundRig) {    /* No RIGs present, look for RI8 and CI8 */
  791.     /* look for Refset if DFR8ref called, else look for next ref */
  792.         if ((Refset &&
  793.          (DFIfind(dfile, DFTAG_RI8, Refset, 1, 0, 0, &dlep, &cdd)==0)) ||
  794.         (!Refset &&
  795.          (DFIfind(dfile, DFTAG_RI8, DFREF_WILDCARD, !Readrig.image.ref,
  796.               Readrig.image.tag, Readrig.image.ref, &dlep, &cdd)==0)))
  797.             riref = dlep->dd[cdd].ref;
  798.  
  799.         if ((Refset &&
  800.          (DFIfind(dfile, DFTAG_CI8, Refset, 1, 0, 0, &dlep, &cdd)==0)) ||
  801.         (!Refset &&
  802.          (DFIfind(dfile, DFTAG_CI8, DFREF_WILDCARD, !Readrig.image.ref,
  803.               Readrig.image.tag, Readrig.image.ref, &dlep, &cdd)==0)))
  804.             ciref = dlep->dd[cdd].ref;
  805.  
  806.         Refset = 0;
  807.         if (!riref && !ciref) {
  808.             DFerror = DFE_NOMATCH;
  809.             return(-1);
  810.         }
  811.         if ((!ciref) || (riref && (riref<ciref))) { /* next image is RI8 */
  812.             Readrig.image.ref = riref;
  813.             Readrig.image.tag = DFTAG_RI8;
  814.         }
  815.         else {            /* next image is CI8 */
  816.             Readrig.image.ref = ciref;
  817.             Readrig.image.tag = DFTAG_CI8;
  818.             Readrig.descimage.compr.tag = DFTAG_RLE;
  819.         }
  820.  
  821. #ifdef DF_STRUCTOK        /* read in dimensions */
  822.         if (DFgetelement(dfile, DFTAG_ID8, Readrig.image.ref, &im8dim)>=0) {
  823.             Readrig.descimage.xdim = im8dim.xd;
  824.             Readrig.descimage.ydim = im8dim.yd;
  825.         }
  826. #else /*DF_STRUCTOK*/
  827.         if (DFgetelement(dfile, DFTAG_ID8, Readrig.image.ref, DFtbuf)>=0) {
  828.             register char *p;
  829.             p = DFtbuf;
  830.             UINT16READ(p, Readrig.descimage.xdim);
  831.             UINT16READ(p, Readrig.descimage.ydim);
  832.         }
  833. #endif /*DF_STRUCTOK*/
  834.         else return(-1);
  835.  
  836.         if (DFIfind(dfile, DFTAG_IP8, Readrig.image.ref, 1, 0, 0, &dlep,
  837.             &cdd)==0) {
  838.             Readrig.lut.tag = DFTAG_IP8;
  839.             Readrig.lut.ref = Readrig.image.ref;
  840.         }
  841.     }
  842.     Lastref = Readrig.image.ref; /* remember ref read */
  843.     return(0);
  844. }
  845.